<?php

namespace platform\models;

use common\enum\Enum;
use common\models\Circuit;
use common\models\CircuitAddress;
use common\models\PointTime;
use common\models\Shift;
use common\models\Site;
use common\services\Authorization;
use platform\core\BaseModel;
use cm;
use Yii;
use yii\db\Expression;
use yii\helpers\Json;
use yii\helpers\Url;

class ShiftModel extends BaseModel
{
    /*
    * 班次管理
    */
    public function actionIndex()
    {
        $action = Yii::$app->request->get('action');
        if($action=='point'){
            $shift_id = Cm::$req->get('shift_id', ['null', 'empty', 'default' => 0]);
            $shift=Shift::findOne($shift_id);
            $site_id=Circuit::findOne($shift->circuit_id)->site_sid;
            $data['site'] = Site::find()->alias('s')
            ->leftJoin(['ca'=>CircuitAddress::tableName()],['ca.site_id'=>new Expression('s.id')])
            ->leftJoin(['pt'=>PointTime::tableName()],['pt.ca_id'=>new Expression('ca.id')])
            ->andWhere(['pt.shift_id'=>$shift_id])
                ->andWhere(['!=','ca.site_id',$site_id])
            ->select(['s.id','s.name'])
            ->asArray()
            ->all();
            $data['is_heide']=1;
            $data['baseUrl'] = Url::to(['shift/point','shift_id'=>$shift_id]);
            return $data;
        }
        $circuit_id = Cm::$req->get('circuit_id', ['null', 'empty', 'default' => 0]);
        if (Cm::$req->isPost()) {
            switch ($action) {
                case "list":
                    $pageIndex = Cm::$req->post('page', ['null', 'empty', 'default' => 1]);
                    $pageCount = Cm::$req->post('limit', ['null', 'empty', 'default' => 20]);
                    $type = (int)Cm::$req->post('type', ['null', 'empty']);
                    $departuretime = Cm::$req->post('departuretime', ['null', 'empty']);
                    $circuitid = Cm::$req->post('circuit_id', ['null', 'empty', 'default' => 0]);
                    $status = Cm::$req->post('status', ['null', 'empty']);
                    $where = " 1=1 ";
                    $where .= empty($circuitid) ? (empty($circuit_id) ? "" : " AND a.circuit_id={$circuit_id} ") : " AND a.circuit_id={$circuitid}  ";
                    if(!empty($departuretime)){
                        $departuretimearr = explode('至', $departuretime);
                        $stime = trim($departuretimearr[0]);
                        $etime = trim($departuretimearr[1]);
                        $where .= " AND a.departuretime >= '{$stime}' AND a.departuretime<='{$etime}'";
                    }
                    if(!empty($status)){
                        $status = $status == 2 ? 0 : $status;
                        $where .= " AND a.status={$status}";
                    }else{
                        $where .= " AND a.status!=2";
                    }
                    if(!empty($type)){
                        $where .= " AND a.type={$type} ";
                    }
                    $data = Cm::$db->paging("SELECT a.*,c.name,s1.name AS sname,s2.name AS ename,cm.name AS models_name,sm.username AS inspectorname,(SELECT CONCAT_WS(',',SUM(ridership),COUNT(id)) AS num FROM `order` WHERE shift_id=a.id AND status=1 AND order_status!=5) AS orderstr
                            FROM shift a 
                            LEFT JOIN circuit c ON c.id=a.circuit_id
                            LEFT JOIN site s1 ON s1.id=c.site_sid
                            LEFT JOIN site s2 ON s2.id=c.site_eid
                            LEFT JOIN car_models cm ON cm.id=a.models_id
                            LEFT JOIN sys_manager sm ON sm.id=a.inspector
                            WHERE {$where} ORDER BY a.departuretime DESC",
                        $pageIndex, $pageCount);
                    foreach ($data['data'] as $key => &$value) {
                        $value['departuretime'] = date("Y-m-d H:i",strtotime($value['departuretime']));
                        $value['presaletime'] = date("Y-m-d H:i",strtotime($value['presaletime']));
                        $value['closingtime'] = date("Y-m-d H:i",strtotime($value['closingtime']));
                        $value['s_ticketstr'] = $this->checkSticket($value['circuit_id'],$value['id'],$value['s_ticket']);
                        $orderstr = explode(",", $value['orderstr']);
                        $value['passengernum'] = $orderstr[0].'人';
                        $value['ordernum'] = empty($orderstr[1]) ? '0笔' : $orderstr[1].'笔';
                    }
                    Cm::$res->paging($data);
                    break;
                case 'save':
                    $id = Cm::$req->post('id', ['null', 'empty', 'default' => 0]);
                    $ismore = Cm::$req->post('ismore', ['null', 'empty', 'default' => 0]);
                    $mdata = [
                        'circuit_id' => Cm::$req->post('circuit_id',['null','empty','default'=>0]),
                        'ticket_price' => trim(Cm::$req->post('ticket_price',['title'=>'票价'])),
                        'a_ticket' => Cm::$req->post('a_ticket',['null','empty','default'=>0]),
                        's_ticket' => Cm::$req->post('s_ticket',['null','empty','default'=>0]),
                        'carnum' => Cm::$req->post('carnum',['null','empty','default'=>0]),
                        'min' => Cm::$req->post('min',['null','empty','default'=>0]),
                        'max' => Cm::$req->post('max',['null','empty','default'=>0]),
                        'type' => Cm::$req->post('type',['null','empty']),
                        'models_id' => Cm::$req->post('models_id',['null','empty','default'=>0]),
                        'inspector' => Cm::$req->post('inspector',['null','empty','default'=>0]),
                        'updatetime' => date("Y-m-d H:i:s",time())
                    ];
                    $circuit=Circuit::findOne($mdata['circuit_id']);
                    if($circuit['rebate_type']==SysModel::REBATE_TYPE_RATIO){
                        $rebate=sprintf("%.2f",$mdata['ticket_price']*$circuit['rebate']/100);
                    }else{
                        $rebate=$circuit['rebate'];
                    }
                    if($rebate>=$mdata['ticket_price']){
                        Cm::$res->error('分销金额大于等于 该班次票价金额');
                    }
                    if(empty($mdata['circuit_id'])){
                        Cm::$res->error('保存失败,请选择排班的线路');
                    }
                    if(empty($mdata['type'])){
                        Cm::$res->error('保存失败,请选择班次类型');
                    }
                    if(empty($mdata['min'])){
                        Cm::$res->error('保存失败,起订人数为大于0的整数');
                    }
                    if($ismore == 0){
                        $this->savedata($id,$mdata);
                    }else{
                        $this->savemoredata($id,$mdata);
                    }
                    break;
                case 'order':
                    $id = Cm::$req->post('id', ['null', 'empty', 'default' => 0]);
                    if(empty($id)){
                        Cm::$res->error("请选择订单统计的班次");
                    }
                    $order = Cm::$db->all("SELECT COUNT(id) AS num,'isok' AS type FROM `order` WHERE shift_id={$id} AND status=1 AND order_status<>5
                                        UNION ALL
                                        SELECT COUNT(id) AS num,'isno' AS type FROM `order` WHERE shift_id={$id} AND order_status=5
                                        UNION ALL
                                        SELECT COUNT(id) AS num,'pay' AS type FROM `order` WHERE shift_id={$id} AND pay_status=1 AND refund_status=0
                                        UNION ALL
                                        SELECT COUNT(id) AS num,'refund' AS type FROM `order` WHERE shift_id={$id} AND status=2
                                        UNION ALL
                                        SELECT COUNT(id) AS num,'change' AS type FROM `order` WHERE shift_id={$id} AND status=3
                                        UNION ALL
                                        SELECT COUNT(id) AS num,'cancel' AS type FROM `order` WHERE shift_id={$id} AND status=0
                                        UNION ALL
                                        SELECT COUNT(id) AS num,'overtime' AS type FROM `order` WHERE shift_id={$id} AND status=1 AND order_status=5");
                    $info = [];
                    $types = [
                        'isok' => '有效订单',
                        'isno' => '无效订单',
                        'pay' => '支付订单',
                        'refund' => '退款订单',
                        'change' => '改签订单',
                        'cancel' => '取消订单',
                        'overtime' => '超时订单'
                    ];
                    $info['data'] = [
                        'name' => "订单量",
                        'type' => "bar",
                        't' => "n",
                        'data' => [],
                        'label'=> [
                            'show'=> true,
                            'position'=> 'top'
                        ]
                    ];
                    foreach ($order as $s) {
                        $name = $types[$s['type']];
                        $info['name'][] = $name;
                        $info['data']['data'][] = $s['num'];
                    }
                    Cm::$res->susess($info);
                    break;
                case 'startstop':
                    $id = Cm::$req->post('id', ['null', 'empty', 'default' => 0]);
                    $status = Cm::$req->post('status', ['null', 'empty', 'default' => 1]);
                    if($status!=1 && $status!=0){
                        Cm::$res->error('操作错误！');
                    }
                    $str = $status == 1 ? '停用':'启用';
                    $info = Cm::$db->one("SELECT id,status FROM shift WHERE id={$id}");
                    if(empty($info)){
                        Cm::$res->error('请选择要'.$str.'的班次');
                    }
                    if($info['status'] == 2){
                        Cm::$res->error('您选择要'.$str.'的班次不存在');
                    }
                    $status = $status == 1 ? 0 : 1;
                    $mdata = ['status' => $status,'updatetime' => date("Y-m-d H:i:s",time())];
                    Cm::$db->update("shift", $mdata, "id={$id}");
                    Cm::$app->log->authlog(49,$mdata,$id);
                    Cm::$res->susess();
                    break;
                case 'del':
                    $id = Cm::$req->post('id', ['null', 'empty', 'default' => 0]);
                    $info = Cm::$db->one("SELECT id FROM shift WHERE id={$id} AND status!=2");
                    if(empty($info)){
                        Cm::$res->error('请选择要删除的班次！');
                    }
                    $ordernum = Cm::$db->one("SELECT count(*) as num FROM `order` WHERE shift_id={$id} AND status=1 AND order_status!=5");
                    if(!empty($ordernum['num'])){
                        Cm::$res->error('该班次还有有效订单不能删除！');
                    }
                    $mdata = ['status' => 2,'updatetime' => date("Y-m-d H:i:s",time())];
                    Cm::$db->update("shift", $mdata, "id={$id}");
                    Cm::$app->log->authlog(50,$mdata,$id);
                    Cm::$res->susess();
                    break;
            }
        }

        $data['map'] = [];
        $data['map'][] = ['title' => "线路管理", 'url' => Url::to(['circuit/index'])];
        $data['map'][] = ['title' => "班次管理", 'url' => Url::to(['shift/index'])];
        $data['baseUrl'] = Url::to(['shift/index','circuit_id'=>$circuit_id]);
        $data['carModels'] = $this->carModels();
        $data['allInspector'] = $this->getInspector();
        $data['circuit_id'] = $circuit_id;
        $data['allCircuit'] = Cm::$db->all("SELECT id,name FROM circuit WHERE status=1");
        return $data;
    }

    /*
    *保存单个
    */
    private function savedata($id,$mdata){
        $mdata['departuretime'] = Cm::$req->post('departuretime',['null','empty']);
        if(empty($mdata['departuretime'])){
            Cm::$res->error('保存失败,请选择发车时间');        
        }
        $mdata['presaletime'] = Cm::$req->post('presaletime',['null','empty']);
        if(empty($mdata['presaletime'])){
            Cm::$res->error('保存失败,请选择预售时间');        
        }
        $mdata['closingtime'] = Cm::$req->post('closingtime',['null','empty']);
        if(empty($mdata['closingtime'])){
            Cm::$res->error('保存失败,请选择停售时间');        
        }
        if(empty($mdata['models_id'])){
            Cm::$res->error('保存失败,请选择车型');    
        }
        if(empty($mdata['inspector'])){
            Cm::$res->error('保存失败,请选择检票人');        
        }
        if(strtotime($mdata['departuretime'])<=strtotime($mdata['closingtime'])){
            Cm::$res->error('保存失败,发车时间必须大于停售时间');            
        }
        if(strtotime($mdata['closingtime'])<=strtotime($mdata['presaletime'])){
            Cm::$res->error('保存失败,停售时间必须大于预售时间');            
        }
        if(!empty($id)){
            Cm::$db->update('shift', $mdata, "id={$id}");
            Cm::$app->log->authlog(32,$mdata,$id);
        }else{
            $mdata['addtime'] = date('Y-m-d H:i:s');
            $mdata['status'] = 1;
            $exithas = Cm::$db->one("SELECT id FROM shift WHERE circuit_id={$mdata['circuit_id']} AND departuretime='{$mdata['departuretime']}' AND status=1");
            if(empty($exithas)){
                $id = Cm::$db->insert('shift', $mdata);
                if(!$id){
                    Cm::$res->error('保存失败');
                }
                Cm::$app->log->authlog(31,$mdata,$id);
            }else{
                Cm::$res->error('保存失败,该路线的发车时间已存在');
            }
            
        }
        Cm::$res->susess([], '保存成功');  
    }

    /*
    *保存多个
    */
    private function savemoredata($id,$mdata){
        $transaction=Yii::$app->db->beginTransaction();
        try {
            if(!empty($id)){
                Cm::$res->error('保存失败,参数错误');
            }
            $departureday = Cm::$req->post('departureday',['title'=>'发车日期']);
            $presaletime = Cm::$req->post('presaletime',['title'=>'预售时间']);
            $closingtime = Cm::$req->post('closingtime',['title'=>'停售时间']);
            $moretimestr = Cm::$req->post('moretimestr',['title'=>'发车时间']);
            $moretime = empty($moretimestr) ? [] : json_decode($moretimestr);
            $point_times=Yii::$app->request->post('point_times');
            $ca_id=CircuitAddress::find()->alias('ca')
                ->leftJoin(['c'=>Circuit::tableName()],['ca.circuit_id'=>new Expression('c.id')])
                ->andWhere(['c.id'=>$mdata['circuit_id']])
                ->andWhere(new Expression('c.site_sid=ca.site_id'))
                ->select(['ca.id'])->scalar();
            if(!$ca_id){
                Cm::$res->error('原有线路请重新保存后在排班!');
            }
            $point_times[]=[
                'id'=>$ca_id,
                'time'=>$moretime
            ];
            if(empty($departureday)){
                Cm::$res->error('保存失败,请选择发车日期');
            }
            if(empty($presaletime)){
                Cm::$res->error('保存失败,请填写预售时间');
            }
            if(empty($closingtime)){
                Cm::$res->error('保存失败,请填写停售时间');
            }
            if(empty($moretime)){
                Cm::$res->error('保存失败,请选择发车时间');
            }
            $departurearr = explode(' 至 ', $departureday);
            $departuretime = "";
            if($departurearr[0] == $departurearr[1]){
                $departuretime = $departurearr[0];
                $this->addshift($moretime,$departuretime,$presaletime,$closingtime,$mdata,$point_times);
                Cm::$app->log->authlog(31,['point_times'=>$point_times,'mdata'=>$mdata,'moretime'=>$moretime,'departuretime'=>$departuretime,'presaletime'=>$presaletime,'closingtime'=>$closingtime],"批量添加单天班次");
            }else{
                $start = strtotime($departurearr[0]);
                $end = strtotime($departurearr[1]." 23:59:59");
                $day = round(($end-$start)/3600/24);
                for ($i=0; $i <$day ; $i++) {
                    $departuretime = date('Y-m-d',strtotime("+".$i." day",strtotime($departurearr[0])));
                    $this->addshift($moretime,$departuretime,$presaletime,$closingtime,$mdata,$point_times);
                }
                Cm::$app->log->authlog(31,['point_times'=>$point_times,'mdata'=>$mdata,'moretime'=>$moretime,'departuretimearr'=>$departurearr,'presaletime'=>$presaletime,'closingtime'=>$closingtime],"批量添加多天班次");
            }
            $transaction->commit();
            Cm::$res->susess([], '保存成功');
        }catch (\Exception $e){
            $transaction->rollBack();
            Cm::$res->error('保存失败,'.$e->getMessage());
        }
    }

    /*
    *新增班次
    */
    private function addshift($moretime,$departuretime,$presaletime,$closingtime,$mdata,$point_times=[]){
        $time=time();
        foreach ($moretime as $key => $value) {
            $mdata['departuretime'] = $departuretime." ".$value.":00";
            $mdata['presaletime'] = date('Y-m-d H:i:s',strtotime("-".$presaletime." hour",strtotime($mdata['departuretime'])));
            $mdata['closingtime'] = date('Y-m-d H:i:s',strtotime("-".$closingtime." minute",strtotime($mdata['departuretime'])));    
            $mdata['addtime'] = date('Y-m-d H:i:s',$time);
            $mdata['status'] = 1;
            $exithas = Cm::$db->one("SELECT id FROM shift WHERE circuit_id={$mdata['circuit_id']} AND departuretime='{$mdata['departuretime']}' AND status=1");
            $point_data=[];
            foreach ($point_times as $k=>$v){
                $point_data[]=[
                    'id'=>$v['id'],
                    'time'=>$v['time'][$key]
                ];
            }
            $mdata['point_times']=Json::encode($point_data,JSON_UNESCAPED_UNICODE);
            if(empty($exithas)){
                $shift_id=Cm::$db->insert('shift', $mdata);
                $data=[];
                foreach ($point_data as $item){
                        $ca_time=$departuretime." ".$item['time'].":00";
                        $data[]=[
                            'shift_id'=>$shift_id,
                            'ca_id'=>$item['id'],
                            'departuretime'=>$ca_time,
                            'presaletime' => date('Y-m-d H:i:s',strtotime("-".$presaletime." hour",strtotime($ca_time))),
                            'closingtime' => date('Y-m-d H:i:s',strtotime("-".$closingtime." minute",strtotime($ca_time))),
                            'created_at'=>$time,
                            'updated_at'=>$time,
                        ];
                }
                if(count($data)){
                    $res=Yii::$app->db->createCommand()->batchInsert(PointTime::tableName(),array_keys(current($data)),$data)->execute();
                    if($res!=count($data))throw new \Exception('记录数量操作失败-'.$res.'-'.count($data));
                }
            }
        }
    }
}